﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JetBrains.Metadata.Reader.API;
using JetBrains.ReSharper.Psi;

namespace Objectware.Silverlight.Testing.Runner.Resharper
{
	public static class TypeUtility
	{
		public const string TestNamespace = "Microsoft.VisualStudio.TestTools.UnitTesting";
		public const string TestClassAttributeName = TestNamespace+".TestClassAttribute";
		public const string TestMethodAttributeName = TestNamespace+".TestMethodAttribute";
		public const string TestIgnoreAttribute = TestNamespace + ".IgnoreAttribute";

		private static bool IsNullOrEmpty(IList<IMetadataCustomAttribute> list)
		{
			if( null == list || list.Count <= 0 )
			{
				return true;
			}
			return false;
		}

		public static bool IsTestClass(IMetadataTypeInfo typeInfo)
		{
			bool hasAttribute = !IsNullOrEmpty(typeInfo.GetCustomAttributes(TestClassAttributeName));
			bool isPublic = typeInfo.IsPublic;
			return hasAttribute && isPublic;
		}

		public static bool IsTestClass(IClass @class)
		{
			bool hasAttribute = @class.HasAttributeInstance(new CLRTypeName(TestClassAttributeName), true);
			bool isPublic = @class.GetAccessRights() == AccessRights.PUBLIC;
			return hasAttribute && isPublic;
		}


		public static bool IsTestMethod(IMetadataMethod method)
		{
			bool hasAttribute =  !IsNullOrEmpty(method.GetCustomAttributes(TestMethodAttributeName));
			return hasAttribute;
		}


		public static bool IsTestMethod(IMethod method)
		{
			bool hasAttribute = method.HasAttributeInstance(new CLRTypeName(TestMethodAttributeName), true);
			return hasAttribute;
		}

		public static IMethod[] GetTestMethods(ITypeElement typeInfo)
		{
			List<IMethod> methods = new List<IMethod>();
			foreach( IMethod method in typeInfo.Methods )
			{
				if( IsTestMethod(method))
				{
					methods.Add(method);
				}
			}
			return methods.ToArray();
		}

		public static string GetExplicitStringIfIgnored(IMetadataEntity entity)
		{
			IList<IMetadataCustomAttribute> attributes = entity.GetCustomAttributes(TestIgnoreAttribute);
			if( null != attributes && attributes.Count >= 1 )
			{
				return "Test is ignored - reason not available";
			}

			return null;
		}
	}
}
